# 创建Person类
class Person
  attr_reader :name    # 只读
  attr_writer :age     # 只写
  attr_accessor :gender # 读写

  def initialize(name, age)
    @name = name
    @age = age
  end
end

# 创建实例
p = Person.new("李四", 30)
puts p.name      # 可读
p.age = 31       # 可写
p.gender = "男"   # 可读写
puts p # 实例的内存地址 #<Person:0x00000210aab0bcd0>
puts p.inspect # 实例的详细信息 #<Person:0x00000210aab0bcd0 @name="李四", @age=31, @gender="男">


#  类方法与类变量

# 创建 Counter 类
class Counter
  @@count = 0  # 类变量

  # 初始化方法：每次初始化，类变量 @@count += 1
  def initialize
    @@count += 1
  end

  # 类方法定义方式1
  def self.total_count
    @@count
  end

  # 类方法定义方式2
  class << self
    def reset_count
      @@count = 0
    end
  end
end

# 创建3个Counter实例，则会累加三次类变量 @@count = 3
3.times { Counter.new }
# 调用 total_count 方法，输出类变量 @@count
puts Counter.total_count  # 输出: 3
# 重置类变量 @@count = 0
Counter.reset_count
# 再次输出类变量 @@count = 0
puts Counter.total_count  # 输出: 0

# ===========================================
# 类的继承

# 创建 Animal 动物类
class Animal
  # 定义speak方法
  def speak
    "动物叫声"
  end
end

# 创建 Dog 继承 Animal 类
class Dog < Animal
  # 重载 speak 方法
  def speak
    super + ": 汪汪!"
  end
end

dog = Dog.new
puts dog.speak  # 输出: 动物叫声: 汪汪!

# 类的访问控制

# 创建银行账号类
class BankAccount
  # 初始化
  def initialize(balance)
    @balance = balance
  end

  # 公开方法
  def deposit(amount)
    @balance += amount
    log_transaction("存款", amount)
  end

  # 受保护方法
  protected
  def balance
    @balance
  end

  # 私有方法
  private
  def log_transaction(type, amount)
    puts "#{type} #{amount}元"
  end
end

account = BankAccount.new(1000)
account.deposit(500)  # 可以调用
# account.balance     # 报错，受保护方法
# account.log_transaction("测试", 100) # 报错，私有方法

# ===================================================
# 模块混入(Mixin)

# 定义模块：
module Swimmable
  # 定义 swim 方法
  def swim
    "我会游泳!"
  end
end

# 创建 Fish 类
class Fish
  # 混入模块
  include Swimmable
end

# 创建实例
fish = Fish.new
# 调用模块的方法swim
puts fish.swim  # 输出: 我会游泳!